﻿using System;
using System.IO;
using System.IO.Compression;
using Jamhee.Noctiluca.Common;
using Jamhee.Noctiluca.LightWiki.PropertyFiles;
using System.Net;
using Jamhee.Noctiluca.WebServer;
using System.Web;
using System.Collections.Specialized;
using System.Text.RegularExpressions;

namespace Jamhee.Noctiluca.LightWiki.Pages
{
    class AttachmentPageHandler : TextPageHandler
    {
        #region Constants

        private readonly string TEMPLATE_VIEWATTACHMENT = AppUtil.WORK_ROOT + @"\doc\wiki\themes\default\pages\viewattachment.template";
        private readonly string TEMPLATE_VIEWATTACHMENT_LOOP = AppUtil.WORK_ROOT + @"\doc\wiki\themes\default\pages\viewattachment.attachment.loop";

        private const string LOOP_WIKI_ATTACHMENTS = "$(LOOP_WIKI_ATTACHMENTS)";
        private const string WIKI_ATTACHMENT_NAME = "$(WIKI_ATTACHMENT_NAME)";
        private const string WIKI_ATTACHMENT_SIZE = "$(WIKI_ATTACHMENT_SIZE)";
        private const string WIKI_ATTACHMENT_DOWNLOAD = "$(WIKI_ATTACHMENT_DOWNLOAD)";
        private const string WIKI_ATTACHMENT_DELETE = "$(WIKI_ATTACHMENT_DELETE)";
        private const string ATTACHMENT_FOLDER_NAME = "_attachment";

        private const string SAVEPAGE_FILE1 = "file1";
        private const string SAVEPAGE_FILE2 = "file2";
        private const string SAVEPAGE_FILE3 = "file3";
        private const string SAVEPAGE_FILE4 = "file4";
        private const string SAVEPAGE_FILE5 = "file5";

        private const string REG_CONTENT_TYPE = @"multipart\/form-data; boundary=(-*[a-zA-Z0-9]*)";

        #endregion


        #region View page

        protected override string ReplacePageVariable(string docPath, string line, WikiPageInfo pageInfo, bool parseWikiMarkup, Uri url)
        {
            // Replace the title
            if (line.IndexOf(WikiConstants.WIKI_TITLE) >= 0)
            {
                line = line.Replace(WikiConstants.WIKI_TITLE, pageInfo.GetPageTitle());
            }

            // Replace attachment information
            if (line.IndexOf(LOOP_WIKI_ATTACHMENTS) >= 0)
            {
                string attachInfo = "";
                FileInfo fi = new FileInfo(docPath);
                DirectoryInfo dir = new DirectoryInfo(fi.Directory + "\\" + ATTACHMENT_FOLDER_NAME);
                WikiTextLoop attchLoop = new WikiTextLoop(AppUtil.GetAbsolutePath(TEMPLATE_VIEWATTACHMENT_LOOP));

                if (dir.Exists)
                {
                    FileInfo[] files = dir.GetFiles();
                    foreach (FileInfo file in files)
                    {
                        string loopText = attchLoop.GetText();

                        // replace the file name
                        loopText = loopText.Replace(WIKI_ATTACHMENT_NAME, file.Name);

                        // replace the file size
                        loopText = loopText.Replace(WIKI_ATTACHMENT_SIZE, GetFileSize(file.Length));

                        // replace the attachment downloading
                        loopText = loopText.Replace(WIKI_ATTACHMENT_DOWNLOAD, url.AbsolutePath.TrimEnd('/') +
                            "?type=attachment&action=download&file=" + HttpUtility.UrlEncode(file.Name));

                         // replace the attachment deleting
                        loopText = loopText.Replace(WIKI_ATTACHMENT_DELETE, url.AbsolutePath.TrimEnd('/') +
                            "?type=attachment&action=delete&file=" + HttpUtility.UrlEncode(file.Name));


                        attachInfo += loopText;
                    }
                }


                line = line.Replace(LOOP_WIKI_ATTACHMENTS, attachInfo);
            }

            return line;
        }

        private string GetFileSize(long size)
        {
            long fileSize = size;
            string uom = "B";

            if (fileSize > 1024)
            {
                fileSize = fileSize / 1024;
                uom = "KB";
            }

            if (fileSize > 1024)
            {
                fileSize = fileSize / 1024;
                uom = "MB";
            }

            if (fileSize > 1024)
            {
                fileSize = fileSize / 1024;
                uom = "GB";
            }

            if (fileSize > 1024)
            {
                fileSize = fileSize / 1024;
                uom = "TB";
            }

            return fileSize + " " + uom;
        }

        protected override string GetPageTemplateName(UrlQueryResult.ActionType action)
        {
            return TEMPLATE_VIEWATTACHMENT;
        }

        protected override string GetNavigator(System.Uri url, Jamhee.Noctiluca.WebServer.IWebConfiguration webConfig)
        {
            return base.GetNavigator(url, webConfig) + " > Attachment";
        }

        protected override bool HyperLinkForCurrentPageInNavigator
        {
            get { return true; }
        }

        #endregion

        #region Save Page

        public override void Save(string contentDocPath, HttpListenerContext context,
            IWebConfiguration webConfig)
        {
            //Stream input = context.Request.InputStream;
            //StreamReader sr = new StreamReader(input);

            //string redirectURL = null;

            //try
            //{
            //    //FileInfo fi = new FileInfo(contentDocPath);
            //    //WikiPageInfo pageInfo = new WikiPageInfo(Path.GetFullPath(fi.DirectoryName + "\\" + WikiConstants.WIKI_DOC_INFO));

            //    //string line = null;
            //    //NameValueCollection body = null;

            //    //while ((line = sr.ReadLine()) != null)
            //    //{
            //    //    body = HttpUtility.ParseQueryString(line);

            //    //    string filecontent = body.Get(SAVEPAGE_FILE1);
            //    //    if (filecontent != null)
            //    //    {

            //    //    }
            //    //}

            //    //GZipStream stream = new GZipStream(input, CompressionMode.Decompress);
            //    //System.Web.HttpPostedFile file;
            //    //file.
            //    Regex regex = new Regex(REG_CONTENT_TYPE);
            //    string boundary = null;

            //    if (regex.IsMatch(context.Request.ContentType))
            //    {
            //        MatchCollection matches = regex.Matches(context.Request.ContentType);
            //        if (matches[0].Groups.Count == 2)
            //        {
            //            boundary = matches[0].Groups[1].Value;
            //        }
            //    }

            //    if (boundary != null)
            //    {
            //        string line = null;
            //        while ((line = sr.ReadLine()) != null)
            //        {
            //            Console.WriteLine(line);
            //        }
            //    }
            //}
            //catch (Exception e)
            //{
            //    LogUtil.PrintError(e.Message);
            //    throw e;
            //}
            //finally
            //{
            //    if (sr != null)
            //    {
            //        sr.Close();
            //    }
            //}

            //if (redirectURL == null)
            //{
            //    redirectURL = "?type=attachment&action=view";
            //}

            //context.Response.Redirect(redirectURL);
            //context.Response.Close();
        }

        #endregion

        #region Download Page

        public override void Download(string contentDocPath, HttpListenerContext context,
            IWebConfiguration webConfig)
        {
            // Get attachment file path
            NameValueCollection queries = HttpUtility.ParseQueryString(context.Request.Url.Query);
            string filename = queries.Get("file");

            if (filename != null)
            {
                context.Response.ContentType = "application/octet-stream";
                context.Response.Redirect(context.Request.Url.AbsolutePath.TrimEnd('/') + "/" +
                    HttpUtility.HtmlEncode(ATTACHMENT_FOLDER_NAME) + "/" + HttpUtility.UrlEncode(filename));
                context.Response.Close();
            }
            else
            {
                context.Response.StatusCode = 404;
                context.Response.Close();
            }
        }

        #endregion


        #region Delete Page

        public override void Delete(string contentDocPath, HttpListenerContext context,
            IWebConfiguration webConfig)
        {
            // Get attachment file path
            NameValueCollection queries = HttpUtility.ParseQueryString(context.Request.Url.Query);
            string filename = queries.Get("file");

            if (filename != null)
            {
                FileInfo fi = new FileInfo(contentDocPath);
                filename = fi.Directory + "\\" + ATTACHMENT_FOLDER_NAME + "\\" + HttpUtility.UrlDecode(filename);

                if (File.Exists(filename))
                {
                    try
                    {
                        File.Delete(filename);
                    }
                    catch (Exception e)
                    {
                        LogUtil.PrintError(e.Message);
                    }
                }
            }

            context.Response.Redirect(context.Request.Url.AbsolutePath.TrimEnd('/') + "?type=attachment&action=view");
            context.Response.Close();
        }

        #endregion
    }
}
